package com.chat.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chat.admin.domain.DTO.ADD.AddRoleDTO;
import com.chat.admin.domain.DTO.EDIT.EditRoleDTO;
import com.chat.admin.domain.DTO.RoleDTO;
import com.chat.admin.domain.VO.RoleVO;
import com.chat.admin.mapper.RoleMapper;
import com.chat.admin.service.IAuthorityService;
import com.chat.admin.service.IRoleAuthorityMappingService;
import com.chat.admin.service.IRoleService;
import com.chat.common.common.constant.MessageConstant;
import com.chat.common.common.exception.RoutineException;
import com.chat.common.entity.Authority;
import com.chat.common.entity.Role;
import com.chat.common.entity.RoleAuthorityMapping;
import com.chat.common.form.ListForm;
import com.chat.common.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author weikjie
 * @since 2024-05-06
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    IAuthorityService iAuthorityService;

    @Autowired
    IRoleAuthorityMappingService iRoleAuthorityMappingService;

    @Override
    public R<ListForm<RoleVO>> getRoleList(RoleDTO roleDTO) {
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(roleDTO.getName())){
            queryWrapper.eq("name",roleDTO.getName());
        }
        if(StringUtils.isNotBlank(roleDTO.getDescription())){
            queryWrapper.like("description",roleDTO.getDescription());
        }
        if(roleDTO.getState()!=null){
            queryWrapper.eq("state", roleDTO.getState());
        }
        Page<Role> rolePage = new Page<>(roleDTO.getPage(), roleDTO.getSize());
        IPage<Role> roleIPage = page(rolePage, queryWrapper);
        List<Role> roleList = roleIPage.getRecords();
        List<RoleVO> roleVOList = convertToRoleVO(roleList);
        ListForm<RoleVO> roleListForm = new ListForm<>(roleDTO.getPage(),roleDTO.getSize(),
                roleIPage.getPages(), //总页数
                roleIPage.getTotal(), //总记录数total
                roleVOList);
        return R.succeed(roleListForm);
    }

    @Override
    @Transactional
    public R insertRole(AddRoleDTO addroleDTO) {
        Role role = new Role();
        role.setName(addroleDTO.getName());
        role.setDescription(addroleDTO.getDescription());
        role.setCreationTime(LocalDateTime.now());
        int insert = baseMapper.insert(role);
        if (insert != 0){
            // 获取角色ID
            Long roleId = role.getId();
            if(addroleDTO.getAuthIdList() != null && !addroleDTO.getAuthIdList().isEmpty()){
                // 验证权限列表里面的权限id是否是正确的
                areAuthoritiesValid(addroleDTO.getAuthIdList());
                // 创建角色和权限的关系列表
                List<RoleAuthorityMapping> roleAuthorityMappings = convertToRoleAuthorityMappingList(roleId, addroleDTO.getAuthIdList());
                Integer integer = iRoleAuthorityMappingService.BatchInsertion(roleAuthorityMappings);
                if(integer != 0){
                    return R.succeed("添加成功");
                } else {
                    throw new RoutineException("角色" + MessageConstant.ADD_ERROR);
                }
            }
            return R.succeed("添加成功");
        } else {
            throw new RoutineException("角色" + MessageConstant.ADD_ERROR);
        }
    }

    @Override
    @Transactional
    public R updateRole(EditRoleDTO editroleDTO) {
        Role role = new Role();
        role.setId(editroleDTO.getId());
        role.setName(editroleDTO.getName());
        role.setDescription(editroleDTO.getDescription());
        int update = baseMapper.updateById(role);
        if (update != 0){
            if(editroleDTO.getAuthIdList() != null && !editroleDTO.getAuthIdList().isEmpty()){
                areAuthoritiesValid(editroleDTO.getAuthIdList());
                Long roleId = role.getId();
                iRoleAuthorityMappingService.deleteRoleAuthority(roleId);
                List<RoleAuthorityMapping> roleAuthorityMappings = convertToRoleAuthorityMappingList(roleId, editroleDTO.getAuthIdList());
                Integer integer = iRoleAuthorityMappingService.BatchInsertion(roleAuthorityMappings);
                if(integer != 0){
                    return R.succeed("修改成功");
                } else {
                    throw new RoutineException("角色" + MessageConstant.EDIT_ERROR);
                }
            }
            return R.succeed("修改成功");
        } else {
            throw new RoutineException("角色" + MessageConstant.EDIT_ERROR);
        }
    }

    @Override
    public R<?> EnableRole(Long ID) {
        // 创建一个 UpdateWrapper 对象
        UpdateWrapper<Role> updateWrapper = new UpdateWrapper<>();
        // 设置 id 等于 userID 的条件
        updateWrapper.eq("id", ID);
        // 设置 state 属性为 false
        updateWrapper.set("state", true);
        // 执行更新操作
        boolean result = update(updateWrapper);
        // 根据更新结果返回相应的响应
        if (result) {
            return R.succeed("角色已成功启用");
        } else {
            return R.failed("启用角色失败");
        }
    }

    @Override
    public R<?> DisableRole(Long ID) {
        // 创建一个 UpdateWrapper 对象
        UpdateWrapper<Role> updateWrapper = new UpdateWrapper<>();
        // 设置 id 等于 userID 的条件
        updateWrapper.eq("id", ID);
        // 设置 state 属性为 false
        updateWrapper.set("state", false);
        // 执行更新操作
        boolean result = update(updateWrapper);
        // 根据更新结果返回相应的响应
        if (result) {
            return R.succeed("角色已成功禁用");
        } else {
            return R.failed("禁用角色失败");
        }
    }

    @Override
    public List<Role> getStateRoles() {
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("state", 1);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public Map<Long, Role> getStateRolesMap() {
        // 从数据库获取角色列表
        List<Role> roles = this.getStateRoles();
        // 使用 Java 8 Stream API 将 List<Role> 转换为 Map<Long, Role>
        return roles.stream()
                .collect(Collectors.toMap(Role::getId, role -> role));
    }

    @Override
    public Boolean isRoleValid(Long roleID) {
        if (roleID == null) {
            return false;
        }
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", roleID) // 检查id是否匹配
                .eq("state", 1); // 假设状态为1表示有效
        return baseMapper.selectCount(queryWrapper) > 0;
    }

    List<RoleAuthorityMapping> convertToRoleAuthorityMappingList(Long roleId, List<Long> entityList){
        List<RoleAuthorityMapping> relations = new ArrayList<>();
        for (Long permissionId : entityList) {
            RoleAuthorityMapping relation = new RoleAuthorityMapping();
            relation.setRoleId(roleId);
            relation.setAuthorityId(permissionId);
            relations.add(relation);
        }
        return relations;
    }

    private void areAuthoritiesValid(List<Long> authoritiesIds){
        Boolean authorityBoolean = iAuthorityService.areAuthoritiesValid(authoritiesIds);
        if(!authorityBoolean ){
            throw new RoutineException(MessageConstant.AUTH_ID_LIST_ERROR );
        }
    }


    private List<RoleVO> convertToRoleVO(List<Role> roleList) {
        List<RoleVO> roleVOList = new ArrayList<>();
        List<Authority> stateAuthorities = iAuthorityService.getStateAuthorities();
        List<RoleAuthorityMapping> roleAuthorityMappingList = iRoleAuthorityMappingService.list();

        // 将所有激活的权限ID存储在一个集合中以便快速查找
        Set<Long> activeAuthorityIds = stateAuthorities.stream()
                .map(Authority::getId)
                .collect(Collectors.toSet());

        for (Role role : roleList) {
            RoleVO roleVO = new RoleVO();
            BeanUtil.copyProperties(role, roleVO);
            roleVO.setState(role.getState() == 1);

            // 从映射列表中找到当前角色的所有权限映射
            List<Long> authorityIds = roleAuthorityMappingList.stream()
                    .filter(mapping -> mapping.getRoleId().equals(role.getId()) &&
                            activeAuthorityIds.contains(mapping.getAuthorityId()))
                    .map(RoleAuthorityMapping::getAuthorityId)
                    .collect(Collectors.toList());

            // 设置权限ID列表到RoleVO
            roleVO.setAuthIdList(authorityIds);
            roleVOList.add(roleVO);
        }
        return roleVOList;
    }
}